TITL DAI FIRMWARE 1E22B-1E413 V1.1 ORG :E22B * * * ******************** * INTEGER DIVISION * ******************** * * Signed 32-bit fixed point division: * MACC = MACC / MEM. * * Entry: HL: Points to divisor. * Exit: All registers preserved. * XIDIV PUSH PSW PUSH B PUSH D PUSH H CALL :E242 Signed division CALL :E3CF Quotient into MACC JMP :C14D Popall, ret * ************************ * INT DIVIDE REMAINDER * ************************ * * For INT values: MACC = Remainder of (MACC / MEM). * * Entry: HL: Points to divisor. * Exit: All registers preserved. * XIREM PUSH PSW PUSH B PUSH D PUSH H CALL :E242 Signed division; REM Remainder in MACC JMP :C14D Popall, ret * *************************** * SIGNED INTEGER DIVISION * *************************** * * Divides MACC / MEM; quotient is left in registers * B,C,D,E and the remainder in MACC. * * Entry: HL: Points to divisor. * MACC: Dividend. * Exit: BCDE: Quotient; remainder in MACC. * S-flag: Set for result. * AHL: Corrupted, CY=0. * L1E24 CALL :ED8F Get signbyte dividend in A, REM compare it with sign divisor MOV A,B Get signbyte dividend PUSH PSW Save result compare CALL :EA0E Copy divisor into BCDE MOV A,B ) ORA C ) Check if divisor = 0 ORA D ) ORA E ) JZ :E2E4 Then error 'divide by zero' MOV A,B Get signbyte divisor ORA A Is it negative ? CM :E3C9 Then negate divisor JC :E2E4 Error exit if overflow PUSH B ) Save divisor on stack PUSH D ) CALL :E2EC Normalize divisor CMA ) H = pos. value of nr of INR A ) times shifted for norma- MOV H,A ) lisation LDA :00D5 Get signbyte dividend ORA A Is dividend negative ? CM :E315 Then change sign dividend CALL :E3D6 Copy dividend in reg BCDE ORA C ) ORA D ) Check if dividend zero ORA E ) JZ :E2E0 Then abort, leaving 0000 in REM MACC and reg BCDE CALL :E2EC Normalize dividend; nrs of REM shifts in A POP D ) Restore divisor in BCDE POP B ) ADD H Add nr of shifts for divisor REM H is total nrs of shifts JM :E2C9 If resulting nrs of shifts REM < 0 then result = 0000 CALL :EB39 Shift divisor left (A) times PUSH D ) Save shifted divisor on PUSH B ) stack LXI B,:8000 Init BCDE for max neg number LXI D,:0000 CALL :EB55 Shift BCDE right (A) times MOV H,B ) Shifted BC in HL MOV L,C ) POP B Get hibytes shifted divisor XTHL HL: lobytes shifted divisor; REM shifted BC on stack XCHG DE: lobytes shifted divisor; REM HL: shifted DE PUSH H Shifted DE on stack L1E25 LHLD :00D7 Get lobytes dividend MOV A,H ) SUB E ) MOV H,A ) (00D7/8)=(00D7/8)-lobytes MOV A,L ) shifted divisor SBB D ) MOV L,A ) SHLD :00D7 ) LHLD :00D5 Get hibytes dividend MOV A,H ) SBB C ) MOV H,A ) (00D5/6)=(00D5/6)-hibytes MOV A,L ) shifted divisor SBB B ) MOV L,A ) SHLD :00D5 ) L1E26 POP H Get shifted DE RAL CMC MOV A,L RAL MOV L,A MOV A,H RAL MOV H,A XTHL Get shifted 'BC' in HL MOV A,L RAL MOV L,A MOV A,H RAL MOV H,A XTHL New 'BC' back on stack JC :E2D0 CALL :EB70 Rotate BCDE right 1 bit MOV A,L RAR PUSH H New 'DE' back on stack JC :E28E CY=1: again CALL :E2F2 MACC = MACC + BCDE JMP :E2A6 Again REM * If resulting nr of shifts is negative: REM L1E27 LXI D,:0000 PUSH D JMP :E2D7 BCDE = 0000; abort REM * If ready: REM L1E28 MOV A,L RAR PUSH H CNC :E2F2 CY=0: MACC = MACC + BCDE POP D L1E29 POP B POP PSW Get result sign compare CALL :ED88 Evt negate BCDE CM :E315 Evt change sign MACC RET REM * If dividend is zero: REM L1E30 POP H ) Save BCDE = 0000 POP H ) POP PSW RET REM * If errors: REM L1E31 CC :C04B CY=1: Run overflow error CZ :C06C Z=1: Run divide by 0 error POP PSW RET * ********************************************* * INT: NORMALIZE CONTENTS REGISTERS B,C,D,E * ********************************************* * * Exit: HL preserved. * L1E32 PUSH H CALL :EBA0 Normalize BCDE (INT) POP H RET * ****************************************** * ADD CONTENTS REGISTERS B,C,D,E TO MACC * ****************************************** * * Exit: BCDE preserved, AHL corrupted. * F set on hibyte of result. * L1E33 LHLD :00D7 ) MOV A,H ) ADD E ) Add DE to 00D7/8 MOV H,A ) MOV A,L ) ADC D ) MOV L,A SHLD :00D7 LHLD :00D5 MOV A,H ) ADC C ) MOV H,A ) Add BC to 00D5/6 MOV A,L ) ADC B ) MOV L,A ) SHLD :00D5 RET * *********** * INT ABS * *********** * * For INT values: MACC = absolute value of MACC. * * Exit: All registers preserved. * XIABS PUSH PSW LDA :00D5 Get sign byte ORA A CM :E315 If <0: change sign POP PSW RET * ********************************** * INT: CHANGE SIGN MACC CONTENTS * ********************************** * * For INT values: MACC = - MACC. * * Exit: All registers preserved. * XICHS PUSH PSW PUSH B PUSH D PUSH H CALL :E3D6 Copy MACC into reg BCDE CALL :E3C9 Negate BCDE JNC :E328 Jump if no error REM * If overflow error: REM L1E36 CALL :C04B Run overflow error JMP :C14D Popall, ret REM * If O.K.: REM L1E37 CALL :E3CF Copy reg BCDE into MACC JMP :C14D Popall, ret * ******** * IAND * ******** * * Logical 'AND': MACC = MACC IAND MEM. * * Entry: HL points to operand in memory. * Exit: All registers preserved. * XIAND PUSH PSW PUSH B PUSH D PUSH H JMP :ECE1 Prepare IAND and perform * **************** * PERFORM IAND * **************** * * Performs: MEM IAND EBCA, result in ABCD. * * Entry: HL points to last byte of MEM. * Fixed point number in EBCA. * Exit: HL points to 1st byte of MEM. * E preserved. * SIAND ANA M MOV D,A DCX H MOV A,C ANA M MOV C,A DCX H MOV A,B ANA M MOV B,A DCX H MOV A,E ANA M RET * L1E40 DBL :E385 (not used) * ******* * IOR * ******* * * Logical 'OR': MACC = MACC IOR MEM. * * Entry: HL points to operand in memory. * Exit: All registers preserved. * XIOR PUSH PSW PUSH B PUSH D PUSH H JMP :ECEA Prepare IOR and perform * *************** * PERFORM IOR * *************** * * Performs MEM IOR EBCA. Result in ABCD. * * Entry: HL points to last byte of MEM. * Fixed point nr in EBCA. * Exit: HL points to 1st byte of MEM. * E preserved. * SIOR ORA M MOV D,A DCX H MOV A,C ORA M MOV C,A DCX H MOV A,B ORA M MOV B,A DCX H MOV A,E ORA M RET * L1E43 DBL :E385 (not used) * ******** * IXOR * ******** * * Logical 'XOR': MACC = MACC IXOR MEM. * * Entry: HL points to operand in memory. * Exit: All registers preserved. * XIXOR PUSH PSW PUSH B PUSH D PUSH H JMP :ECF3 Prepare IXOR and perform * **************** * PERFORM IXOR * **************** * * Performs MEM IXOR EBCA, result in ABCD. * * Entry: HL points last byte of MEM. * Fixed point number in EBCA. * Exit: HL points to 1st byte of MEM. * E preserved. * SIXOR XRA M MOV D,A DCX H MOV A,C XRA M MOV C,A DCX H MOV A,B XRA M MOV B,A DCX H MOV A,E XRA M RET * L1E46 DBL :E385 (not used) * ******** * INOT * ******** * * Logical 'INOT': MACC = INOT (MACC). * * Exit: All registers preserved. * XINOT PUSH PSW PUSH B PUSH D PUSH H CALL :ECFC Copy MACC into ABCD; CMA MOV E,A Save hibyte MOV A,D CMA INOT D MOV D,A MOV A,C CMA INOT C MOV C,A MOV A,B CMA INOT B MOV B,A L1E48 MOV A,E Get back hibyte L1E49 CALL :E126 Copy ABCD into MACC JMP :C14D Popall, ret * L1E50 RET (not used) * *********************************** * COPY MACC INTO REG. E,B,C,A * * D = compl. 00D5 EXOR hibyte MEM * *********************************** * * Entry: HL points to 1st byte MEM. * Exit: HL points to last byte MEM. * D = complement EXOR hibytes MACC and MEM. * Msb D = 1: sign bits identical. * Msb D = 0: sign bits different. * L1E51 JMP :ED01 Copy MACC into ABCD, A in E; REM jump to E38F * L1E52 XRA M EXOR sign bytes CMA Complement result INX H INX H INX H PUSH D MOV D,A A = compl EXOR signbytes POP PSW Get D in A RET * ******* * SHR * ******* * * MACC = MACC SHR MEM. * Shifts contents MACC right (MEM) places. * * Entry: HL points to operand in memory. * Exit: All registers preserved. * Result is 0 if MEM < 0 or > 31. * XSHR PUSH PSW PUSH B PUSH D PUSH H CALL :ED08 Check MEM. If <=31: REM MACC into BCDE, shift in A REM Else: clear ABCDE CALL :EB55 Shift BCDE right A places JMP :E328 BCDE into MACC; quit * ******* * SHL * ******* * * MACC = MACC SHL MEM. * Shifts contents MACC left (MEM) places. * * Entry/exit: See XSHR. * XSHL PUSH PSW PUSH B PUSH D PUSH H CALL :ED08 Check MEM. If <= 31: MACC REM into BCDE, shift in A REM Else: clear ABCDE CALL :EB39 Shift BCDE left A places JMP :E328 BCDE into MACC; quit * ******************************* * TEST VALUE OF AN INT NUMBER * ******************************* * * Tests if an INT has a value between 0 and 31. * If true: Number into A, else: Clear ABCDE. * * Entry: HL points to a 4-byte number. * Exit: Nr <= #1F: Number in A. * Nr > #1F: ABCDE cleared. * HL points to 4th byte in memory. * XSTST MOV A,M Get 1st byte INX H ORA M OR with 2nd INX H ORA M OR with 3rd INX H JNZ :E3C2 Jump if highest bytes <>0 MOV A,M Get 4th byte ANI :E0 Test 3 highest bits NOP NOP MOV A,M Get 4th byte in A RZ Abort if 4th byte <= #1F REM * If nr > #1F: REM L1E56 MVI A,:00 ) MOV B,A ) MOV C,A ) Clear ABCDE MOV D,A ) MOV E,A ) RET * ****************************************** * INT: NEGATE CONTENTS REGISTERS B,C,D,E * ****************************************** * * Exit: HL preserved. * CY=1: Overflow into msb. * L1E57 PUSH H CALL :EB82 Negate BCDE (INT) POP H RET * ************************************ * COPY REGISTERS B,C,D,E INTO MACC * ************************************ * * Entry: none. * Exit: ABCD corrupted, FHL preserved. * L1E58 MOV A,B MOV B,C MOV C,D MOV D,E JMP :E126 Copy ABCD into MACC * ************************************ * COPY MACC INTO REGISTERS B,C,D,E * ************************************ * * Entry: None. * Exit: AFHL preserved. * L1E59 PUSH PSW CALL :E133 Copy MACC into ABCD JMP :ED13 Copy ABCD into BCDE * L1E60 RET * ******************************* * CHANGE CONTENTS MACC TO FPT * ******************************* * * Result is incorrect if MACC = 80 00 00 00. * Then exponent is 1 too high (E3FC should be * a NOP instruction). * * Entry: None. * Exit: All registers preserved. * XFLT PUSH PSW PUSH B PUSH D PUSH H CALL :E3D6 Copy MACC into BCDE CALL :ED83 Check if BCDE is 0. JZ :E40E Then clear MACC + BCDE MVI H,:20 Init exp.byte for pos.nr MOV A,B ) ORA A ) Check sign bit JP :E3FD Jump if nr is positive REM * If INT nr is negative: REM MVI H,:A0 Init exp.byte for neg.nr CALL :E3C9 Negate BCDE JNC :E3FD Jump if no overflow MVI B,:80 INR H REM * Convert to FPT: REM L1E62 MOV A,H Get init.exp.byte LXI H,:00D5 Addr MACC MOV M,A Init.exp.byte in MACC PUSH H CALL :EB96 Normalize BCDE POP H MOV A,M Get init.exp.byte CALL :E9DB Copy ABCD into MACC JMP :C14D Popall, ret REM * If INT number is 0: REM L1E63 CALL :EA16 Clear MACC + reg ABCD JMP :C14D Popall; ret * * * END